<template>
  <svg v-if="!!properties"
    :width="properties.svg.width" 
    :height="properties.svg.height" 
    v-svgDrag ="properties.svg.draggable?properties.svg:null"
    :style="{left:properties.svg.x+'px',top:properties.svg.y+'px'}"
    >
    <defs>
      <template v-for="flt in properties.fills">
        <linearGradient v-if="flt.type==='linear'" :id="flt.id" :x1="flt.values.x1" :y1="flt.values.y1" :x2="flt.values.x2" :y2="flt.values.y2">
            <template v-for="stop in flt.values.stops">
                <stop :offset="stop.pos" :style="{stopColor:stop.color,stopOpacity:stop.opacity}"></stop>
            </template>
        </linearGradient>
        <radialGradient v-else-if="flt.type==='radial'" :id="flt.id" :cx="flt.values.cx" :cy="flt.values.cy" :r="flt.values.r" :fx="flt.values.fx" :fy="flt.values.fy">
            <template v-for="stop in flt.values.stops">
                <stop :offset="stop.pos" :style="{stopColor:stop.color,stopOpacity:stop.opacity}"></stop>
            </template>
        </radialGradient>
      </template>
      <template v-for="flt in properties.filters">
        <filter v-if="flt.type==='point'" :id="flt.id" color-interpolate-filter="sRGB" :x="flt.values.x" :y="flt.values.y">
            <feDiffuseLighting in="SourceGraphic"
                :lighting-color="flt.values.color"
                :surfaceScale="flt.values.scale"
                :diffuseConstant="flt.values.constant"
                result="diffuseOutput">
                <fePointLight :x="flt.values.lx" :y="flt.values.ly" :z="flt.values.lz"/>
            </feDiffuseLighting>
            <feComposite in1="diffuseOutput" in2="SourceGraphic" operator="in" result="diffuseOutput"></feComposite>
            <feBlend in1="diffuseOutput" in2="SourceGraphic" mode="screen"></feBlend>
        </filter>
      </template>
    </defs>
    <template v-for="group in properties.groups">
        <g v-bind="group" :fill="properties.fills.find(item=>item.id===group.fillId)?`url(#${group.fillId})`:group.fill">
            <template v-for="element in properties.elements">
                <template v-if="element.groupId===group.id">
                    <component 
                        :is="element.type" 
                        :id="element.id" 
                        v-bind="element.values"
                        :filter="`url(#${element.values.filter})`"
                        :fill="properties.fills.find(item=>item.id===element.values.fillId)?`url(#${element.values.fillId})`:element.values.fill" >
                        {{element.values.text}}
                    </component>
                </template>
            </template>
        </g>
    </template>
    <template v-for="an in config.animations">
        <animate v-if="an.type==='animate'"
            :attributeName="an.params.attributeName"
            :from="an.params.from"
            :to="an.params.to"
            :dur="an.params.dur"
            :fill="an.params.fill"
            :repeatCount="an.params.repeatCount"
            :repeatDur="an.params.repeatDur"
            :begin="an.params.begin"
            :calcMode="an.params.calcMode"
            :keyTimes="an.params.keyTimes"
            :values="an.params.values"
            :xlink:href="`#${an.params.href}`"
        ></animate>
        <animateTransform v-if="an.type==='translate'||an.type==='rotate'||an.type==='scale'"
            attributeName="transform"
            :type="an.params.type"
            :from="an.params.from"
            :to="an.params.to"
            :dur="an.params.dur"
            :fill="an.params.fill"
            :repeatCount="an.params.repeatCount"
            :repeatDur="an.params.repeatDur"
            :begin="an.params.begin"
            :calcMode="an.params.calcMode"
            :keyTimes="an.params.keyTimes"
            :values="an.params.values"
            :xlink:href="`#${an.params.href}`"
        ></animateTransform>
        <animateMotion v-else-if="an.type==='motion'"
            :path="an.params.path"
            :dur="an.params.dur"
            :fill="an.params.fill"
            :repeatCount="an.params.repeatCount"
            :repeatDur="an.params.repeatDur"
            :begin="an.params.begin"
            :calcMode="an.params.calcMode"
            :keyTimes="an.params.keyTimes"
            :values="an.params.values"
            :xlink:href="`#${an.params.href}`"
        ></animateMotion>
    </template>
  </svg>
</template>

<script>
import {cloneDeep,merge} from 'lodash';
export default {
  name: "semiCircleSvg",
  data(){
    return {
        properties:null
    }
  },
  props:{
    config:{
      default:()=>{
        return {
            
        }
      }
    },
  },
  computed:{
    fills(){
        return this.config.fills.map(fill=>{
            if(!!this[fill.type+'Tpl']){
                return merge(this[fill.type+'Tpl'](),fill)
            }
        })
    },
    elements(){
        return this.config.elements.map(element=>{
            if(element.type==='semiCircle'){
                return {
                    id:element.id,
                    groupId:element.groupId,
                    type:'path',
                    values:this.semiCircle(element.values)
                }
            }else if(element.type==='polygon'){
                return {
                    id:element.id,
                    groupId:element.groupId,
                    type:'polygon',
                    values:this.polygon(element.values)
                }
            }else{
                return element;
            }
        })
    }
  },
  mounted() {
    this.setProperties();
  },
  watch:{
    'config':{
        handler(){
            this.setProperties();
        },
        deep:true

    }
  },
  methods:{
    
    setProperties(){
        this.properties = {
            id:this.config.id,
            svg:this.config.svg,
            fills:this.fills,
            filters:this.config.filters,
            groups:this.config.groups,
            elements:this.elements
        }
        return this.properties
    },
    linearTpl(){
        return {
            id:'linear1',
            type:'linear',
            values:{
                x1:'0%',
                y1:'0%',
                x2:'100%',
                y2:'0%',
                stops:[
                    {pos:'0%',color:'gray',opacity:1},
                    {pos:'40%',color:'gray',opacity:1},
                    {pos:'70%',color:'gray',opacity:1},
                    {pos:'90%',color:'gray',opacity:1},
                    {pos:'100%',color:'gray',opacity:1},
                ]
            }
        }
    },
    radialTpl(){
        return {
            id:'radial1',
            type:'radial',
            values:{
                cx:'70%',
                cy:'50%',
                r:'50%',
                fx:'50%',
                fy:'50%',
                stops:[
                    {pos:'0%',color:'gray',opacity:1},
                    {pos:'40%',color:'white',opacity:1},
                    {pos:'70%',color:'gray',opacity:1},
                    {pos:'90%',color:'white',opacity:1},
                    {pos:'100%',color:'gray',opacity:1},
                ]
            }
        }
    },
    semiCircle(config){
        let cfg = {
            x:config.x,
            y:config.y,
            cx:Number(config.width)/2+config.x,
            cy:Number(config.height)+config.y,
            rx:Number(config.width)/2,
            ry:Number(config.height),
        }
        let finalCfg ={
            d: `M ${cfg['x']} ${cfg['y']+cfg['ry']} A ${cfg['rx']} ${cfg['ry']} 0 0 1 ${cfg['x']+2*cfg['rx']} ${cfg['y']+cfg['ry']}`,
            stoke:config.stoke,
            stokeWidth:config.stokeWidth,
            fillId:config.fillId,
            fill:config.fill,
            filter:config.filter,
        }
        return finalCfg;
    },
    polygon(cfg){
        return {
            points:`${cfg.x1},${cfg.y1} ${cfg.x2},${cfg.y2} ${cfg.x3},${cfg.y3} ${cfg.x4},${cfg.y4} `,
            stoke:cfg.stoke,
            fillId:cfg.fillId,
            fill:cfg.fill,
            filter:cfg.filter,
            stokeWidth:cfg.stokeWidth,
        }
    }
  }
}
</script>

<style scoped>

</style>
// repeatCount：动画重复执行次数

// repeatDur：动画重复执行总时间

// begin：规定动画开始的时间/什么时间触发了再执行动画
// begin=“1s”：1s后开始执行动画
// begin=“click”：click触发事件执行了再执行动画
// begin=“click + 1s”：点击之后，等两秒再执行动画

// restart: 规定元素开始动画之后，是否可以被重新开始执行
// always：动画可以在任何时候被重置。这是默认值。
// whenNotActive：只有在动画没有被激活的时候才能被重置，例如在动画结束之后，才能再执行。
// never：在整个SVG执行的过程中，元素动画不能被重置。

// calcMode: 规定每一个动画片段的动画表现
// linear：默认属性值, 匀速动画
// discrete: 非连续动画, 没有动画效果瞬间完成
// paced: 规定整个动画效果始终以相同的速度进行，设置keyTimes属性无效
// spline: 配合keySplines属性来定义各个动画过渡效, 自定义动画

// keyTimes:
// 划分动画时间片段, 取值0-1

// values:
// 划分对应取值片段的值